//
//  SLBluetoothManager.m
//  SlockApp
//
//  Created by 凯朱 on 2024/8/6.
//

#import "SLBluetoothManager.h"
#import <CommonCrypto/CommonCryptor.h>
#import "AESCipher.h"
#import "SLAddLockScanVC.h"
#import "SLIbeaconManager.h"
@interface SLBluetoothManager()<CBCentralManagerDelegate,CBPeripheralDelegate>{
    CBManagerState _cbStatus;
    CBPeripheral *_tryPeripheral;//尝试连接的蓝牙设备
    CBCharacteristic *_curCharacteristic;//当前的蓝牙服务特征值
    NSString *_searchDeviceUUID;
    int _timeIntervalTimeout;
}
@property (nonatomic, strong)NSString *curCommond;
@property (nonatomic, strong)NSMutableArray *baseInfoCommonds;
@property (nonatomic, strong)NSMutableDictionary *baseInfo;

@property (nonatomic, strong)NSMutableArray *logInfoCommonds;
@property (nonatomic, strong)NSMutableArray *logInfo;
@property (nonatomic,copy)SLBluetoothDataBlock getLogInfoBlock;

@property (nonatomic, strong)NSMutableArray *statusInfoCommonds;
@property (nonatomic, strong)NSMutableDictionary *statusInfo;

@property (nonatomic, strong)NSMutableArray *settingInfoCommonds;
@property (nonatomic, strong)NSMutableDictionary *settingInfo;

@property (nonatomic, strong)CBCentralManager *centralManager;
@property (nonatomic, strong)NSTimer *timer;
@property (nonatomic, assign)CGFloat time;
@property (nonatomic, strong)NSMutableData *openLogBufferData;/*持续性数据包*/
@property (nonatomic, strong)NSMutableData *keyBufferData;/*持续性数据包*/
@property (nonatomic, strong)NSMutableData *warnBufferData;/*持续性数据包*/
@property (nonatomic, strong)id commondValue;//发送指令时携带的参数 - 临时的

//升级用到
@property (nonatomic, strong)NSData *firmwareData;//固件包数据
@property (nonatomic, assign)NSUInteger packetSize;//每包数据大小
@property (nonatomic, assign)NSInteger packetIndex;//当前包数
//通用消息回调
@property (nonatomic,copy)SLBluetoothNotifyBlock notifyBlock;
//设备状态变更回调 - 所有设备主动向app发送的消息走这个回调
@property (nonatomic,copy)SLBluetoothStatusBlock statusNotifyBlock;
//更新固件回调
@property (nonatomic,copy)SLUpdateFirmwareBlock updateFirmwareBlock;
@property (nonatomic,copy)SLSearchDeviceBlock searchDeviceBlock;
@property (nonatomic,copy)SLConnectDeviceBlock connectDeviceBlock;
//获取设备基本信息回调
@property (nonatomic,copy)SLBluetoothDataBlock getBaseInfoBlock;
//获取状态信息回调
@property (nonatomic,copy)SLBluetoothDataBlock getStatusInfoBlock;
//获取设置信息回调
@property (nonatomic,copy)SLBluetoothDataBlock getSettingInfoBlock;
//获取设备下的钥匙数据回调
@property (nonatomic,copy)SLGetFingerDatasBlock getFingerDatasBlock;
//删除钥匙回调
@property (nonatomic,copy)SLBluetoothNotifyBlock deleteUserFingerBlock;
//蓝牙开锁回调
@property (nonatomic,copy)SLBluetoothNotifyBlock openLockBlock;
//断开连接回调
@property (nonatomic,copy)SLDisConnectBlock disConnectBlock;
//录入指纹回调
@property (nonatomic,copy)SLCreateFingerBlock createFingerBlock;

@property (nonatomic,copy)SLBluetoothNotifyBlock bindDeviceBlock;
@property (nonatomic,copy)SLBluetoothNotifyBlock unBindDeviceBlock;
@property (nonatomic,copy)SLBluetoothNotifyBlock editFingerBlock;
@property (nonatomic,copy)SLBluetoothNotifyBlock setVoiceBlock;
@property (nonatomic,copy)SLBluetoothNotifyBlock setVibrationAlarmBlock;
@property (nonatomic,copy)SLBluetoothNotifyBlock setBurningAlarmBlock;
@property (nonatomic,copy)SLBluetoothNotifyBlock setEnergyModelBlock;
@property (nonatomic,copy)SLBluetoothNotifyBlock setDbModelBlock;
@property (nonatomic,copy)SLBluetoothNotifyBlock setWifiOpenModelBlock;
@property (nonatomic,copy)SLBluetoothNotifyBlock setBlueToothOpenModelBlock;
@property (nonatomic,copy)SLBluetoothDataBlock getOpenLogDatasBlock;
@property (nonatomic,copy)SLBluetoothDataBlock getWarnLogDatasBlock;

@property (nonatomic,copy)SLBluetoothNotifyBlock setWifiBlock;
@property (nonatomic,copy)SLBluetoothNotifyBlock setMqttBlock;
@property (nonatomic,copy)SLBluetoothNotifyBlock setConnectWifiBlock;
@property (nonatomic,copy)SLBluetoothNotifyBlock getMacAddressBlock;

@end

@implementation SLBluetoothManager

+(instancetype)sharedManager{
    static SLBluetoothManager * instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] init];
    });
    return instance;
}

//开始搜索设备
-(void)startSearchDevice:(BOOL)isBridge finish:(SLSearchDeviceBlock)finish{
    if (!_centralManager) {
        _centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
    }
    _isSearching = YES;
    _isConnecting = NO;
    _autoConnectDeviceNo = @"";
    _searchDeviceBlock = finish;
    _searchDeviceUUID = isBridge ? @"0219" : @"";
    if (_searchDeviceUUID.length == 0) {
        [self.centralManager scanForPeripheralsWithServices:nil options:nil];
    }else{
        CBUUID *serviceUUID = [CBUUID UUIDWithString:_searchDeviceUUID];
        NSArray *servicesArr = [NSArray arrayWithObjects:serviceUUID,nil];
        [self.centralManager scanForPeripheralsWithServices:servicesArr options:nil];
    }
    [self startTimerWithBusiType:@"searchDevice"];
}

//开始搜索设备并且连接设备
-(void)startSearchDeviceAndConnect:(NSString *)deviceNo isBridge:(BOOL)isBridge finish:(SLConnectDeviceBlock)finish{
    if (kCurDevice && [kCurDevice.deviceNo isEqualToString:deviceNo]) {
        _connectDeviceBlock = finish;
        if (self.connectDeviceBlock) {
            if (self.connectDeviceBlock) self.connectDeviceBlock(YES,_curPeripheral,nil,@"");
        }
        return;
    }
    NSLog(@"开始连接 %@",deviceNo);
    _isSearching = YES;
    _isConnecting = YES;
    _autoConnectDeviceNo = deviceNo;
    
    _connectDeviceBlock = finish;
    if (!_centralManager) {
        _centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
    }
    _searchDeviceUUID = isBridge ? @"0219" : @"";
    if (_searchDeviceUUID.length == 0) {
        [self.centralManager scanForPeripheralsWithServices:nil options:nil];
    }else{
        CBUUID *serviceUUID = [CBUUID UUIDWithString:_searchDeviceUUID];
        NSArray *servicesArr = [NSArray arrayWithObjects:serviceUUID,nil];
        [self.centralManager scanForPeripheralsWithServices:servicesArr options:nil];
    }
    [self startTimerWithBusiType:@"searchDevice"];
}

//停止搜索设备
-(void)stopSearchDevice{
    _isSearching = NO;
    [self.centralManager stopScan];
    [self destoryTimer];
}

//断开蓝牙连接
-(void)disConnectPeripheral{
    if (_curPeripheral) {
        [_centralManager stopScan];
        [self.centralManager cancelPeripheralConnection:_curPeripheral];
        [self clearCurDeviceData];
    }
}

-(void)clearCurDeviceData{
    _isSearching = NO;
    _isConnecting = NO;
    _curPeripheral = nil;
    _curLockModel = nil;
    _autoConnectDeviceNo = @"";
    _tryPeripheral = nil;
}

//开始计时
-(void)startTimerWithBusiType:(NSString *)busiType{
    // 设置扫描搜索设备时长
    _timeIntervalTimeout = 5;
    if (!_timer && _timer.isValid == NO) {
        _time = 0;
        
        if ([busiType isEqualToString:@"searchDevice"]) {//搜索蓝牙计时器
            _timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(checkSearchStatus) userInfo:nil repeats:YES];
        }else if ([busiType isEqualToString:@"connectPeripheral"]){//连接蓝牙超时
            _timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(checkConnectStatus) userInfo:nil repeats:YES];
        }else if ([busiType isEqualToString:@"openLock"]){//开锁超时
            _timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(checkOpenLockStatus) userInfo:nil repeats:YES];
        }else if ([busiType isEqualToString:@"commondTimeout"]){
            _timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(checkCommondTimeoutStatus) userInfo:nil repeats:YES];
        }
        [_timer fire];
    }
}

-(void)destoryTimer{
    if (_timer) {
        _time = 0;
        [_timer invalidate];
        _timer = nil;
    }
}

-(void)checkCommondTimeoutStatus{
    _time ++;
    if (_time >= _timeIntervalTimeout) {
        [self destoryTimer];
        [ZCTool hideLoadingOnKeyWindow];
    }
}

-(void)checkSearchStatus{
    _time ++;
    //5秒提示
    if (_time >= _timeIntervalTimeout) {
        [self stopSearchDevice];
        if (_isConnecting) {
            _isConnecting = NO;
            _autoConnectDeviceNo = @"";
            if (self.connectDeviceBlock) self.connectDeviceBlock(NO,nil,nil, kLocalString(@"Search time out!"));
        }else{
            if (self.searchDeviceBlock) self.searchDeviceBlock(NO,nil,nil, kLocalString(@"Search time out!"));
        }
    }
}

-(void)checkConnectStatus{
    _time ++;
    //5秒提示
    if (_time >= _timeIntervalTimeout) {
        [self stopSearchDevice];
        _isConnecting = NO;
        _autoConnectDeviceNo = @"";
        if (self.connectDeviceBlock) self.connectDeviceBlock(NO,nil,nil,kLocalString(@"Connect time out!"));
    }
}

-(void)checkOpenLockStatus{
    _time ++;
    //开锁5秒提示
    if (_time >= _timeIntervalTimeout) {
        [self destoryTimer];
        if (_notifyBlock)_notifyBlock(@"39",NO, @"",@"Time out");
    }
}




#pragma mark - ================<蓝牙搜索相关>===============
- (void)centralManagerDidUpdateState:(CBCentralManager *)central{
    _cbStatus = central.state;
    switch (central.state) {
        case CBManagerStateUnknown:
            NSLog(@"CBManagerStateUnknown");
            break;
        case CBManagerStateResetting:
            NSLog(@"CBManagerStateResetting");
            break;
        case CBManagerStateUnsupported:
            NSLog(@"CBManagerStateUnsupported");
            break;
        case CBManagerStateUnauthorized:
            NSLog(@"CBManagerStateUnauthorized");
            break;
        case CBManagerStatePoweredOff:
            NSLog(@"CBManagerStatePoweredOff");
            [self disConnectPeripheral];
            break;
        case CBManagerStatePoweredOn:
            NSLog(@"CBManagerStatePoweredOn");
            if (_isConnecting && _autoConnectDeviceNo.length > 0) {
                [self startSearchDeviceAndConnect:_autoConnectDeviceNo isBridge:[self isBridge] finish:_connectDeviceBlock];
            }else if (_isSearching){
                [self startSearchDevice:[self isBridge] finish:_searchDeviceBlock];
            }
            break;
    }
}

#pragma mark -- 扫描发现设备
-(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI {
    // 将发现的蓝牙设备添加到数组中
    if (!peripheral.name || peripheral.name.length == 0) {
        return;
    }
    NSLog(@"【NAME】Discovered peripheral : name = %@ uuid = %@", peripheral.name, peripheral.identifier.UUIDString);
    NSString *msg1 = [NSString stringWithFormat:@"【NAME】扫描到设备 name=%@, uuid=%@",peripheral.name, peripheral.identifier.UUIDString];
    NSLog(@"%@",msg1);
    [UserManager updateLogViewWithMessage:msg1 needUnicode:NO];
    //蓝牙锁搜索结果
    if (_searchDeviceUUID.length == 0 && !([peripheral.name isEqualToString:@"Padlock G1"] || [peripheral.name isEqualToString:@"HF"])) {
        return;
    }
    
    NSDictionary *deviceInfo =  [self parseAdvertisementData:advertisementData];
    NSString *deviceNo = kSTRING(deviceInfo[@"deviceNo"]);
    NSString *isBindFlag = kSTRING(deviceInfo[@"isBindFlag"]);
    if (deviceNo.length == 0) return;
    NSString *msg2 = [NSString stringWithFormat:@"扫描到设备 deviceInfo %@ ,%@",deviceInfo,peripheral];
    NSLog(@"%@",msg2);
    [UserManager updateLogViewWithMessage:msg1 needUnicode:NO];
    if (_autoConnectDeviceNo.length > 0) {//自动连接
        if ([deviceNo isEqualToString:_autoConnectDeviceNo]) {
            NSString *msg2 = [NSString stringWithFormat:@"尝试连接连接的设备： %@ ,%@",_autoConnectDeviceNo,peripheral];
            NSLog(@"%@",msg2);
            [UserManager updateLogViewWithMessage:msg2 needUnicode:NO];
            [self stopSearchDevice];
            _autoConnectDeviceNo = @"";
            [self connectDevice:peripheral];
        }
    }else{
        //搜索到了相关的未绑定的设备
        BOOL isFind = [isBindFlag isEqualToString:@"0"];
        if ([ZCTool isOpenDebugModel]) isFind = YES;
        if (_isSearching && isFind) {
            [self destoryTimer];
        }
        dispatch_main_async_safe(^{
            if (self.searchDeviceBlock) self.searchDeviceBlock(YES,peripheral,deviceInfo, @"");
        });
    }
}

#pragma mark - ================<蓝牙连接相关>===============
//第一步 - 连接相机蓝牙
-(void)connectDevice:(CBPeripheral *)peripheral{
    _tryPeripheral = peripheral;
    //第一步
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self.centralManager connectPeripheral:peripheral options:nil];
    });
}

//连接蓝牙失败
-(void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error{
    _isConnecting = NO;
    _autoConnectDeviceNo = @"";
    if (self.connectDeviceBlock) self.connectDeviceBlock(NO,peripheral,nil,error.localizedDescription);
}

//断开连接回调
-(void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error{
    if (peripheral == _curPeripheral) {
        [self clearCurDeviceData];
    }
}

-(void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
//    NSString *str = [NSString stringWithFormat:@"Connected to peripheral: %@ state = %ld", peripheral.name,peripheral.state];
    //开始扫描服务服务
    if (peripheral.state == CBPeripheralStateConnected) {
        _isConnecting = NO;
        _autoConnectDeviceNo = @"";
        _curPeripheral = peripheral;
        _curPeripheral.delegate = self;
        //服务id
//        CBUUID *serviceUUID = [CBUUID UUIDWithString:@"0000fff0-0000-1000-8000-00805f9b34fb"];
        [_curPeripheral discoverServices:nil];
    }
}

// 如果需要连接到发现的设备,可以实现这些方法
-(void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{
    if (error){
        if (self.connectDeviceBlock) self.connectDeviceBlock(NO,peripheral,nil,error.localizedDescription);
        return;
    }
    if (peripheral.services.count == 0) {
        return;
    }
    //扫描特征
    [peripheral.services enumerateObjectsUsingBlock:^(CBService * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        [peripheral discoverCharacteristics:nil forService:obj];
    }];
}

// 扫描特征
-(void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{
    if (error){
        if (self.connectDeviceBlock) self.connectDeviceBlock(NO,peripheral,nil,error.localizedDescription);
        return;
    }
    //监听服务并且开始准备通讯
    for (CBCharacteristic *characteristic in service.characteristics) {
        if(characteristic.properties == CBCharacteristicPropertyNotify){//通知特征
            [_curPeripheral setNotifyValue:YES forCharacteristic:characteristic];
        }
        if ([self isBridge]) {
            if ([characteristic.UUID.UUIDString isEqualToString:@"FF01"]) {
                [_curPeripheral setNotifyValue:YES forCharacteristic:characteristic];
                _curCharacteristic = characteristic;
            }
        }else{
            if ([characteristic.UUID.UUIDString isEqualToString:@"1A01"]) {
                _curCharacteristic = characteristic;
            }
        }
    }
  
    if (self.connectDeviceBlock) self.connectDeviceBlock(YES,_curPeripheral,nil,@"");
    
    //连上设备第一时间同步设备时间
    if (![self isBridge]) {
        [[SLBluetoothManager sharedManager] sysncDeviceTime];
    }
}

-(BOOL)isBridge{
    BOOL result = [_searchDeviceUUID isEqualToString:@"0219"];
    return result;
}

#pragma mark - ================<蓝牙消息回调处理>===============
//发送指令回调
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error{
    if (error) {
        if (_notifyBlock)_notifyBlock(0,NO, nil, error.localizedDescription);
    }else{
        NSData *data = characteristic.value;
        if (data.length < 5) {
            if (_notifyBlock)_notifyBlock(0,NO, nil, kLocalString(@"Data unInvaliable"));
        }else{//数据解析完成
            [self handleNotifyWith:data];
        }
    }
}

#pragma mark -
#pragma mark - ================<统一处理蓝牙消息>===============
-(void)handleNotifyWith:(NSData *)data{
    [self destoryTimer];
    NSString *msg = [NSString stringWithFormat:@"收到回复：\n,length-%ld\ndata %@",data.length,[data printHexString]];
    NSLog(@"%@",msg);
    [UserManager updateLogViewWithMessage:msg needUnicode:NO];
    //指令
    NSData *commondData = [data subdataWithRange:NSMakeRange(3,1)];
    NSString *commond = [DataCoverTool coverFromHexDataToStr:commondData];
    //数据
    NSData *playoadData = [data subdataWithRange:NSMakeRange(4, data.length - 6)];
    
    //网关设置wifi
    if ([commond isEqualToString:@"10"]) {
        NSString *result = [DataCoverTool coverFromHexDataToStr:playoadData];
        BOOL isSuccess = [result isEqualToString:@"00"];
        if (_setWifiBlock)_setWifiBlock(commond,isSuccess, @"",@"");
        return;
    }
    //网关设置MQTT主题
    if ([commond isEqualToString:@"12"]) {
        NSString *result = [DataCoverTool coverFromHexDataToStr:playoadData];
        BOOL isSuccess = [result isEqualToString:@"00"];
        if (_setMqttBlock)_setMqttBlock(commond,isSuccess, @"",@"");
        return;
    }
    //网关开始连接wifi
    if ([commond isEqualToString:@"14"]) {
        NSString *result = [DataCoverTool coverFromHexDataToStr:playoadData];
        BOOL isSuccess = [result isEqualToString:@"00"];
        if (_setConnectWifiBlock)_setConnectWifiBlock(commond,isSuccess, @"",@"");
        return;
    }
    //网关macaddress
    if ([commond isEqualToString:@"15"]) {
        NSString *hexStr = [DataCoverTool coverFromHexDataToStr:playoadData];
        NSString *orgMacStr = [DataCoverTool coverFromHexStringToStr:hexStr];
        NSString *macStr = [self parseMacAddressFromString:orgMacStr];
        if (_getMacAddressBlock)_getMacAddressBlock(commond,YES, macStr,@"");
        return;
    }
    
    //设备向app主动上报的数据
    if ([commond isEqualToString:@"5c"]) {
        [self handleDeviceToAppData:commond playoadData:playoadData];
        return;
    }
    
    //查询基本信息
    NSLog(@"=============> _baseInfoCommonds 111: %@, commond: %@", _baseInfoCommonds, commond);
    if ([_baseInfoCommonds containsObject:commond]) {
        [_baseInfoCommonds removeObject:commond];
       
        if ([commond isEqualToString:@"60"]) {
            NSString *macStr = [self macStringFromData:playoadData];
            [_baseInfo setObject:macStr forKey:@"mac"];
            kCurClickDevice.mac = macStr;
        } else if ([commond isEqualToString:@"63"]) {
            NSString *hexStr = [DataCoverTool coverFromHexDataToStr:playoadData];
            NSString *firmwareStr = [DataCoverTool coverFromHexStringToStr:hexStr];
            [_baseInfo setObject:firmwareStr forKey:@"version"];
            kCurClickDevice.firmware = firmwareStr;
        } else if ([commond isEqualToString:@"62"]) {
            // 转16进制字符串
            NSString *hexStr = [DataCoverTool coverFromHexDataToStr:playoadData];
            // 16进制字符串转可显示字符串
            NSString *snStr = [DataCoverTool coverFromHexStringToStr:hexStr];
            [_baseInfo setObject:snStr forKey:@"sn"];
            kCurClickDevice.serialNumber = snStr;
        }
        if (_baseInfoCommonds.count == 0) {
            if (_getBaseInfoBlock)  _getBaseInfoBlock(_baseInfo);
            [_baseInfoCommonds removeAllObjects];
            _baseInfo = nil;
        }
    }
    //查询设置信息
    else if ([_settingInfoCommonds containsObject:commond]) {
        [_settingInfoCommonds removeObject:commond];
//        @"2B",@"2C",@"28",@"29",@"20"
        NSString *keyStr;NSString *valueStr;
        NSString *result = [DataCoverTool coverFromHexDataToStr:playoadData];
        if ([commond isEqualToString:@"28"]) {//震动报警
            keyStr = @"isOpenStrikingAlarm";
            valueStr = [result isEqualToString:@"01"] ? @"1" : @"0";
        }else if ([commond isEqualToString:@"29"]){//高温报警
            keyStr = @"isOpenBurningAlarm";
            valueStr = [result isEqualToString:@"01"] ? @"1" : @"0";
        }else if ([commond isEqualToString:@"2b"]){//双模模式
            keyStr = @"isOpenDbModel";
            valueStr = [result isEqualToString:@"01"] ? @"1" : @"0";
        }
        else if ([commond isEqualToString:@"2e"]){//是否禁用wifi开锁
            keyStr = @"isOpenWifiModel";
            valueStr = [result isEqualToString:@"01"] ? @"1" : @"0";
        }
        else if ([commond isEqualToString:@"2f"]){//是否禁用蓝牙开锁
            keyStr = @"isOpenBlueToothModel";
            valueStr = [result isEqualToString:@"01"] ? @"1" : @"0";
        }
        else if ([commond isEqualToString:@"2d"]){//节能模式
            keyStr = @"isOpenEnergyModel";
            valueStr = [result isEqualToString:@"01"] ? @"1" : @"0";
        }else if ([commond isEqualToString:@"20"]){//音量设置
            keyStr = @"voice";
            if ([result isEqualToString:@"01"]) {
                valueStr = @"1";
            }else if ([result isEqualToString:@"02"]){
                valueStr = @"2";
            }else if ([result isEqualToString:@"03"]){
                valueStr = @"3";
            }else{
                valueStr = @"0";
            }
        }
        if (keyStr.length > 0) {
            [_settingInfo setObject:kSTRING(valueStr) forKey:keyStr];
        }
        if (_settingInfoCommonds.count == 0) {
            if (_getSettingInfoBlock)  _getSettingInfoBlock(_settingInfo);
            [_settingInfoCommonds removeAllObjects];
            _settingInfo = nil;
        }
    }
    //查询状态信息
    else if ([_statusInfoCommonds containsObject:commond]) {
        [_statusInfoCommonds removeObject:commond];
       
        if ([commond isEqualToString:@"40"]) {
            NSString *hexStr = [DataCoverTool coverFromHexDataToStr:playoadData];
            NSInteger level = [DataCoverTool coverFromHexStrToInt:hexStr];
            //0x00~0x64（0~100显示电量） 0x65：充电中 0x66：已充满
            BOOL isCharge = level == 101 || level == 102;
            [_statusInfo setObject:kSTRING(@(level)) forKey:@"batteryLevel"];
            [_statusInfo setObject:kSTRING(@(isCharge)) forKey:@"isCharge"];
        }else if ([commond isEqualToString:@"45"]){
            NSString *hexStr = [DataCoverTool coverFromHexDataToStr:playoadData];
            NSInteger level = [DataCoverTool coverFromHexStrToInt:hexStr];
            [_statusInfo setObject:kSTRING(@(level)) forKey:@"temperature"];
        }
        if (_statusInfoCommonds.count == 0) {
            if (_getStatusInfoBlock) _getStatusInfoBlock(_statusInfo);
            [_statusInfoCommonds removeAllObjects];
            _statusInfo = nil;
        }
    }
    //查询开锁日志数据
    else if ([commond isEqualToString:@"5e"]){
        NSData *resultData = [playoadData subdataWithRange:NSMakeRange(0,1)];
        int result = [[DataCoverTool coverFromHexDataToStr:resultData] intValue];
        //解析出钥匙数据包
        if (result == 1) {//同步结束
            if (_openLogBufferData.length == 0) {
                NSLog(@"无开锁记录数据");
                if (_getOpenLogDatasBlock) _getOpenLogDatasBlock(@[]);
                return;
            }
            
            NSLog(@"同步开锁记录结束 openLogData = %@",[_openLogBufferData printHexString]);
            NSArray *openLogDatas = [self parseOpenLogFromData:_openLogBufferData];
            if (_getOpenLogDatasBlock) _getOpenLogDatasBlock(openLogDatas);
        }else{
            NSData *logData = [playoadData subdataWithRange:NSMakeRange(1,playoadData.length-1)];
            NSLog(@"同步开锁记录中...");
            [_openLogBufferData appendData:logData];
        }
    }
    //查询钥匙数据
    else if ([commond isEqualToString:@"04"]){
        NSData *resultData = [playoadData subdataWithRange:NSMakeRange(0,1)];
        int result = [[DataCoverTool coverFromHexDataToStr:resultData] intValue];
        //解析出钥匙数据包
        NSData *keyData = [playoadData subdataWithRange:NSMakeRange(2,playoadData.length-2)];
        if (result == 1) {//同步结束
            if (_keyBufferData.length == 0) {
                NSLog(@"无钥匙数据");
                if (_getFingerDatasBlock) _getFingerDatasBlock(YES,@[]);
                return;
            }
            NSLog(@"同步钥匙数据结束 fingerData = %@",[_keyBufferData printHexString]);
            NSArray *keyDatas = [self parseFingerFromData:_keyBufferData];
            //查询成员id的钥匙
            NSMutableArray *userKeyDatas = [[NSMutableArray alloc] init];
            if ([_commondValue isKindOfClass:[NSString class]] && kSTRING(_commondValue).length > 0) {
                [keyDatas enumerateObjectsUsingBlock:^(SLLockKeyModel *model, NSUInteger idx, BOOL * _Nonnull stop) {
                    if ([model.uid isEqualToString:_commondValue]) {
                        [userKeyDatas addObject:model];
                    }
                }];
                keyDatas = [[NSArray alloc] initWithArray:userKeyDatas];
            }
            if (_getFingerDatasBlock) _getFingerDatasBlock(YES,keyDatas);
        }else{//同步中
            NSLog(@"同步钥匙数据中...");
            [_keyBufferData appendData:keyData];
        }
    }
    //录入指纹钥匙
    else if ([commond isEqualToString:@"01"]) {
        NSString *inputResult = [DataCoverTool coverFromHexDataToStr:[playoadData subdataWithRange:NSMakeRange(1 ,1)]];
        NSString *curStep = [DataCoverTool coverFromHexDataToStr:[playoadData subdataWithRange:NSMakeRange(playoadData.length-2,1)]];
        NSString *accessId = [DataCoverTool coverFromHexDataToStr:[playoadData subdataWithRange:NSMakeRange(playoadData.length-4,2)]];
        NSString *uid = [DataCoverTool coverFromHexDataToStr:[playoadData subdataWithRange:NSMakeRange(playoadData.length-5,1)]];
        int status = [[DataCoverTool coverFromHexDataToStr:[playoadData subdataWithRange:NSMakeRange(playoadData.length-1,1)]] intValue];
        NSString *accessIdStr = [NSString stringWithFormat:@"%llu",[DataCoverTool coverFromHexStrToInt:accessId]];
        NSLog(@"录入指纹 阶段%@ 第%@次采集 状态%d 成员id %@ 保存id %@",inputResult,curStep,status,uid,accessIdStr);
        if (self.createFingerBlock) self.createFingerBlock(inputResult,curStep,accessIdStr,status);
    }
    //绑定设备
    else if ([commond isEqualToString:@"3b"]){
        NSString *result = [DataCoverTool coverFromHexDataToStr:playoadData];
        BOOL isSuccess = [result isEqualToString:@"00"];
        if (_bindDeviceBlock)_bindDeviceBlock(commond,isSuccess, @"",result);
    }
    //解绑设备
    else if ([commond isEqualToString:@"3a"]){
        NSString *result = [DataCoverTool coverFromHexDataToStr:playoadData];
        BOOL isSuccess = [result isEqualToString:@"00"];
        if (_unBindDeviceBlock)_unBindDeviceBlock(commond,isSuccess, @"",result);
    }
    //删除钥匙
    else if ([commond isEqualToString:@"02"] ){
        NSString *result = [DataCoverTool coverFromHexDataToStr:[playoadData subdataWithRange:NSMakeRange(playoadData.length-1,1)]];
        BOOL isSuccess = [result isEqualToString:@"ff"];
        if (_deleteUserFingerBlock)_deleteUserFingerBlock(commond,isSuccess, @"",result);
    }
    //修改钥匙
    else if ([commond isEqualToString:@"03"]){
        NSString *result = [DataCoverTool coverFromHexDataToStr:[playoadData subdataWithRange:NSMakeRange(playoadData.length-1,1)]];
        BOOL isSuccess = [result isEqualToString:@"ff"];
        if (_editFingerBlock)_editFingerBlock(commond,isSuccess, @"",result);
    }
    //设置音量
    else if ([commond isEqualToString:@"20"]) {
        if (_setVoiceBlock)_setVoiceBlock(commond,YES, @"",@"");
    }
    //设置震动报警 - 防撬
    else if ([commond isEqualToString:@"28"]) {
        if (_setVibrationAlarmBlock)_setVibrationAlarmBlock(commond,YES, @"",@"");
    }
    else if ([commond isEqualToString:@"29"]) {
        if (_setBurningAlarmBlock)_setBurningAlarmBlock(commond,YES, @"",@"");
    }
    else if ([commond isEqualToString:@"2d"]) {
        if (_setEnergyModelBlock)_setEnergyModelBlock(commond,YES, @"",@"");
    }
    else if ([commond isEqualToString:@"2b"]) {
        if (_setDbModelBlock)_setDbModelBlock(commond,YES, @"",@"");
    }
    else if ([commond isEqualToString:@"2e"]) {
        if (_setWifiOpenModelBlock)_setWifiOpenModelBlock(commond,YES, @"",@"");
    }
    else if ([commond isEqualToString:@"2f"]) {
        if (_setBlueToothOpenModelBlock)_setBlueToothOpenModelBlock(commond,YES, @"",@"");
    }
    
    //蓝牙开锁
    else if ([commond isEqualToString:@"39"]) {
        [self destoryTimer];
        NSData *resultData = [playoadData subdataWithRange:NSMakeRange(0,1)];
        int result = [[DataCoverTool coverFromHexDataToStr:resultData] intValue];
        BOOL isSuccess = result == 0;
        NSString *tipMsg;
        if (result == 1) {
            tipMsg = kLocalString(@"Open faild");
        }else if (result == 2){
            tipMsg = kLocalString(@"Unlock via bluetooth is disable");
        }
        
        if (_openLockBlock)_openLockBlock(commond,isSuccess, @"",tipMsg);
    }
    //OTA模式开启
    else if ([commond isEqualToString:@"a0"]) {
        NSString *result = [DataCoverTool coverFromHexDataToStr:playoadData];
        //开启失败
        if ([result isEqualToString:@"01"]) {
            if (_updateFirmwareBlock)_updateFirmwareBlock(NO,-1,kLocalString(@"Set Ota model faild"));
        }else{
            //设置OTA参数例如150k = 153,600（0x25800）0x00 0x02 0x58 0x00
            NSData *paramsData = [self dataFromInteger:_firmwareData.length];
            [self sendCommandWith:0xA1 paramsData:paramsData];
        }
    }
    //设置OTA模式参数
    else if ([commond isEqualToString:@"a1"]) {
        NSString *packetHexStr = [DataCoverTool coverFromHexDataToStr:[playoadData subdataWithRange:NSMakeRange(playoadData.length-2,2)]];
        _packetSize = [DataCoverTool coverFromHexStrToInt:packetHexStr];
        //获取到每包的数据大小 - 开始传输
        [self startUploadFirmwareData];
    }
    //OTA - 上传固件包回调 - 每个包回调一次
    else if ([commond isEqualToString:@"a2"]){
        NSString *result = [DataCoverTool coverFromHexDataToStr:playoadData];
        //数据正常 - 继续传输
        if ([result isEqualToString:@"00"]) {
            int total = (int)(_firmwareData.length / _packetSize);
            if (_packetIndex == total) {//最后一个包传输完成
                [self stopUploadFirmwareData];
            }else{
                _packetIndex ++;
                //计算进度
                if (_updateFirmwareBlock)_updateFirmwareBlock(YES,(CGFloat)_packetIndex/total,kLocalString(@"Upload progress"));
                [self startUploadFirmwareData];
            }
        }
        //数据异常
        else{
            if (_updateFirmwareBlock)_updateFirmwareBlock(NO,-1,kLocalString(@"Upload firmware faild"));
        }
    }
    //OTA结束
    else if ([commond isEqualToString:@"a3"]){
        NSString *result = [DataCoverTool coverFromHexDataToStr:playoadData];
        //升级完成
        if ([result isEqualToString:@"00"]) {
            if (_updateFirmwareBlock)_updateFirmwareBlock(YES,999,kLocalString(@"Update success"));
        }else{
            if (_updateFirmwareBlock)_updateFirmwareBlock(NO,-1,kLocalString(@"Update faild"));
        }
    }
}

//处理设备主动发给app的信息
-(void)handleDeviceToAppData:(NSString *)commond playoadData:(NSData *)playoadData{
    //告警信息
    if ([commond isEqualToString:@"5c"]) {
        NSArray *warnLogDatas = [self parseWarnLogFromData:playoadData];
        //上报告警信息给云端
        [self uploadWarnData:warnLogDatas];
    }
}

-(void)uploadWarnData:(NSArray *)warnLogs{
    if (warnLogs.count == 0) {
        return;
    }
    NSMutableArray *mslUnlockLogList = [NSMutableArray new];
    [warnLogs enumerateObjectsUsingBlock:^(SLLockLogModel *model, NSUInteger idx, BOOL * _Nonnull stop) {
        NSDictionary *warnInfo = @{@"warnType":kSTRING(model.warnType),
                                   @"unlockTime":kSTRING(model.unlockTime),
                                   @"deviceId":kCurClickDevice.deviceId,
                                   @"unlockType":@"99"};
        [mslUnlockLogList addObject:warnInfo];
    }];
    NSDictionary *params = @{@"mslUnlockLogList":mslUnlockLogList,
                             @"deviceId":kCurClickDevice.deviceId};
    
    [ZKHttpManager postWithPath:@"/msl_lock_key/SyncInfo" params:params finished:^(BOOL isSuccessed, id  _Nonnull result, NSString * _Nonnull code, NSString * _Nonnull message) {
        if (isSuccessed) {
            [ZKHttpManager sysncDeviceDataWith:@{@"isHaveNewWarn":@"1"} finished:^(BOOL isSuccessed, id  _Nonnull result, NSString * _Nonnull code, NSString * _Nonnull message) {
                if (isSuccessed) {
                    [[NSNotificationCenter defaultCenter] postNotificationName:@"kRefreshDeviceList" object:@{@"model":kCurDevice}];
                    [[NSNotificationCenter defaultCenter] postNotificationName:@"kWarnRefreshLogVc" object:@{}];
                }
            }];
        }
    }];
}

#pragma mark - ================<蓝牙指令发送封装>===============
//发送指令 如 0x01 添加开锁方式
-(void)sendCommandWith:(int8_t)command paramsData:(NSData *)paramsData{
    // 创建 NSMutableData 对象
    NSMutableData *data = [[NSMutableData alloc] initWithCapacity:0];
    NSMutableData *orData = [[NSMutableData alloc] initWithCapacity:0];
    
    // 帧头 1字节
    int8_t byte0 = 0xFF;
    if ([self isBridge]) byte0 = 0xFA;
    [data appendBytes:&byte0 length:sizeof(byte0)];
    
    // 数据长度 - 2字节
    NSData *lenghData = [DataCoverTool setId:(int)paramsData.length + 2];
    [data appendData:lenghData];
  
    // 指令 1字节
    int8_t byte3 = command;
    [data appendBytes:&byte3 length:sizeof(byte3)];
    
    //异或校验需要的参数 - 数据长度，指令，数据
    [orData appendData:lenghData];
    [orData appendBytes:&byte3 length:sizeof(byte3)];
    if (paramsData) {
        [orData appendData:paramsData];
        [data appendData:paramsData];
    }
    // 计算异或校验
    unsigned char *buffer = (unsigned char *)[orData bytes];
    unsigned short length = (unsigned short)[orData length];
    int8_t byte4 = [self checkCrc:buffer length:length];
    [data appendBytes:&byte4 length:sizeof(byte4)];
    
    // 帧尾 1字节
    int8_t byte5 = 0xFE;
    [data appendBytes:&byte5 length:sizeof(byte5)];
    NSString *tipMsg;
    if (paramsData) {
        tipMsg = [NSString stringWithFormat:@"发送携带参数的指令【%@】 length = %ld <%@>",kCurClickDevice.deviceNo,data.length,[data printHexString]];
    }else{
        tipMsg = [NSString stringWithFormat:@"发送不携带参数的指令【%@】 length = %ld <%@>",kCurClickDevice.deviceNo,data.length,[data printHexString]];
    }
    NSLog(@"%@",tipMsg);
    [UserManager updateLogViewWithMessage:tipMsg needUnicode:NO];
    // 发送指令至蓝牙设备
    if (_curPeripheral) {
        [self sendSegmentedDataToBluetoothDevice:data];
    }else{
        if (self.disConnectBlock) self.disConnectBlock();
    }
}

-(void)sendSegmentedDataToBluetoothDevice:(NSData *)dataToSend{
    // 设置适当的分段大小
   NSString *sengment =  kSTRING([[NSUserDefaults standardUserDefaults] objectForKey:@"sengment"]);
    NSInteger chunkSize = 512;
    if ([sengment intValue] > 0) {
        
    }
    
    NSInteger offset = 0;
    while (offset < dataToSend.length) {
        NSInteger length = MIN(dataToSend.length - offset, chunkSize);
        NSData *chunk = [dataToSend subdataWithRange:NSMakeRange(offset, length)];
//        NSLog(@"分段发送offset=%ld： %@",offset,chunk);
        // 发送分段数据
        if ([self isBridge]) {
            [_curPeripheral writeValue:chunk forCharacteristic:_curCharacteristic type:CBCharacteristicWriteWithResponse];
        }else{
            [_curPeripheral writeValue:chunk forCharacteristic:_curCharacteristic type:CBCharacteristicWriteWithoutResponse];
        }
        offset += length;
    }
}

- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error{
    
//    NSLog(@"didWriteValueForCharacteristic error = %@",error);
}

- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error{
//    NSLog(@"didUpdateNotificationStateForCharacteristic error = %@",error);
}



#pragma mark -
#pragma mark - ================<蓝牙指令封装 - 智锁>===============
/*
 同步设备时间
 */
-(void)sysncDeviceTime{
    NSData *paramsData = [self timeToHexData:[NSDate date]];
    [self sendCommandWith:0x27 paramsData:paramsData];
}

//绑定设备
-(void)bindDeviceWith:(SLBluetoothNotifyBlock)finish{
    _bindDeviceBlock = finish;
    [self sendCommandWith:0x3b paramsData:nil];
    [self startTimerWithBusiType:@"commondTimeout"];
}

//解绑设备
-(void)unBindDeviceWith:(SLBluetoothNotifyBlock)finish{
    _unBindDeviceBlock = finish;
    NSData *paramsData = [self commodParamsWith:@[@"01"]];
    [self sendCommandWith:0x3a paramsData:paramsData];
    [self startTimerWithBusiType:@"commondTimeout"];
}

/*
 查询设备基本信息 - 这里主要封装多个命令，查询完毕一起返回给业务侧
 */
-(void)getDeviceStatusInfo:(SLBluetoothDataBlock)finish{
    _getStatusInfoBlock = finish;
    _statusInfoCommonds = [[NSMutableArray alloc] initWithArray:@[@"40",@"45"]];
    _statusInfo = [[NSMutableDictionary alloc] init];
    [_statusInfoCommonds enumerateObjectsUsingBlock:^(NSString *commondStr, NSUInteger idx, BOOL * _Nonnull stop) {
        int8_t commond = [self int8ValueFromString:commondStr];
        [self sendCommandWith:commond paramsData:nil];
    }];
    [self startTimerWithBusiType:@"commondTimeout"];
}

/*
 查询设备基本信息 - 这里主要封装多个命令，查询完毕一起返回给业务侧
 固件版本号，mac地址，
 */
-(void)getDeviceBaseInfo:(SLBluetoothDataBlock)finish{
    _getBaseInfoBlock = finish;
    _baseInfoCommonds = [[NSMutableArray alloc] initWithArray:@[@"60",@"62",@"63"]];
    _baseInfo = [[NSMutableDictionary alloc] init];
    [_baseInfoCommonds enumerateObjectsUsingBlock:^(NSString *commondStr, NSUInteger idx, BOOL * _Nonnull stop) {
        int8_t commond = [self int8ValueFromString:commondStr];
        [self sendCommandWith:commond paramsData:nil];
    }];
    [self startTimerWithBusiType:@"commondTimeout"];
}

/*
 查询设备设置信息 - 设置页面用到
 */
-(void)getDeviceSettingInfo:(SLBluetoothDataBlock)finish{
    _getSettingInfoBlock = finish;
    _settingInfoCommonds = [[NSMutableArray alloc] initWithArray:@[@"2b",@"2c",@"2d",@"2e",@"2f",@"28",@"29",@"20"]];
    _settingInfo = [[NSMutableDictionary alloc] init];
    [_settingInfoCommonds enumerateObjectsUsingBlock:^(NSString *commondStr, NSUInteger idx, BOOL * _Nonnull stop) {
        int8_t commond = [self int8ValueFromString:commondStr];
        [self sendCommandWith:commond paramsData:nil];
    }];
    [self startTimerWithBusiType:@"commondTimeout"];
}

/*
 设置音量 0-静音 1-低 2-中 3-高
 */
-(void)setDeviceVoice:(NSInteger)voiceLevel finish:(SLBluetoothNotifyBlock)finish{
    _setVoiceBlock = finish;
    NSString *level = [NSString stringWithFormat:@"0%ld",voiceLevel];
    NSData *paramsData = [self commodParamsWith:@[level]];
    [self sendCommandWith:0x20 paramsData:paramsData];
    [self startTimerWithBusiType:@"commondTimeout"];
}

/*
 设置震动报警（防撬）
 yes-开启 no-关闭
 */
-(void)setVibrationAlarm:(BOOL)open finish:(SLBluetoothNotifyBlock)finish{
    _setVibrationAlarmBlock = finish;
    NSString *result = [NSString stringWithFormat:@"0%d",open];
    NSData *paramsData = [self commodParamsWith:@[result]];
    [self sendCommandWith:0x28 paramsData:paramsData];
    [self startTimerWithBusiType:@"commondTimeout"];
}

/*
 设置高温报警
 yes-开启 no-关闭
 */
-(void)setBurningAlarm:(BOOL)open finish:(SLBluetoothNotifyBlock)finish{
    _setBurningAlarmBlock = finish;
    NSString *result = [NSString stringWithFormat:@"0%d",open];
    NSData *paramsData = [self commodParamsWith:@[result]];
    [self sendCommandWith:0x29 paramsData:paramsData];
    [self startTimerWithBusiType:@"commondTimeout"];
}

/*
 设置wifi开锁
 yes-开启 no-关闭
 */
-(void)setAllowWifiOpenModel:(BOOL)open finish:(SLBluetoothNotifyBlock)finish{
    _setWifiOpenModelBlock = finish;
    NSString *result = [NSString stringWithFormat:@"0%d",open];
    NSData *paramsData = [self commodParamsWith:@[result]];
    [self sendCommandWith:0x2e paramsData:paramsData];
    [self startTimerWithBusiType:@"commondTimeout"];
}

/*
 设置蓝牙开锁
 yes-开启 no-关闭
 */
-(void)setAllowBlueToothOpenModel:(BOOL)open finish:(SLBluetoothNotifyBlock)finish{
    _setBlueToothOpenModelBlock = finish;
    NSString *result = [NSString stringWithFormat:@"0%d",open];
    NSData *paramsData = [self commodParamsWith:@[result]];
    [self sendCommandWith:0x2f paramsData:paramsData];
    [self startTimerWithBusiType:@"commondTimeout"];
}

/*
 设置节能模式
 yes-开启 no-关闭
 */
-(void)setEnergyModel:(BOOL)open finish:(SLBluetoothNotifyBlock)finish{
    _setEnergyModelBlock = finish;
    NSString *result = [NSString stringWithFormat:@"0%d",open];
    NSData *paramsData = [self commodParamsWith:@[result]];
    [self sendCommandWith:0x2d paramsData:paramsData];
    [self startTimerWithBusiType:@"commondTimeout"];
}

/*
 设置双模开锁模式
 yes-开启 no-关闭
 */
-(void)setDbModel:(BOOL)open finish:(SLBluetoothNotifyBlock)finish{
    _setDbModelBlock = finish;
    NSString *result = [NSString stringWithFormat:@"0%d",open];
    NSData *paramsData = [self commodParamsWith:@[result]];
    [self sendCommandWith:0x2b paramsData:paramsData];
    [self startTimerWithBusiType:@"commondTimeout"];
}

/*
 开关锁命令
 type 
 0x00：蓝牙关锁
 0x01：蓝牙开锁
 0x02：远程关锁
 0x03：远程开锁
 uid - 0x01~0x64 - 成员id ，钥匙所属成员id，app传入
 */
-(void)openLockWith:(NSString *)openType uid:(NSString *)uid finish:(SLBluetoothNotifyBlock)finish{
    _openLockBlock = finish;
    NSString *uidHex = [DataCoverTool coverFromIntToHex:[uid integerValue]];
    NSData *paramsData = [self commodParamsWith:@[openType,uidHex]];
    [self sendCommandWith:0x39 paramsData:paramsData];
    [self startTimerWithBusiType:@"openLock"];
}

/*
 添加指纹钥匙
 keyModel - 钥匙模型
 isManager - 是否是管理员
 */
-(void)addFingerAccessWith:(SLLockKeyModel *)keyModel isManager:(BOOL)isManager isCancel:(BOOL)isCancel finish:(SLCreateFingerBlock)finish{
    _createFingerBlock = finish;
    //封装参数
    NSMutableData *paramsData = [[NSMutableData alloc] initWithCapacity:0];
    //1-类型 - 指纹
    int8_t byte1 = 0x03;
    [paramsData appendBytes:&byte1 length:sizeof(byte1)];
    //2-阶段 - 开始录入
    int8_t byte2 = isCancel ? 0xfe : 0x00;
    [paramsData appendBytes:&byte2 length:sizeof(byte2)];
    //3-管理员标志
    int8_t byte3 = isManager ? 0x01 : 0x00;
    [paramsData appendBytes:&byte3 length:sizeof(byte3)];
    //4-成员id
    NSString *uidHex = [DataCoverTool coverFromIntToHex:[keyModel.uid integerValue]];
    NSData *byte4 = [self commodParamsWith:@[uidHex]];
    [paramsData appendData:byte4];
    //5-保存id 0xFFFF 固定值 添加完成设备会自动生成一个保存id并返回
    int8_t byte5 = 0xFF;
    [paramsData appendBytes:&byte5 length:sizeof(byte5)];
    [paramsData appendBytes:&byte5 length:sizeof(byte5)];
    //6-时效性 - a.次数为 0x00，此时次数为永久有效，可仅处理时效的循环方式。 b.时效的循环方式为 0x00，此时为不循环，可仅处理次数。
    if (keyModel.keyType == 1) {//永久性钥匙 -17个字节
        int8_t byte_time = 0x00;
        for (int i = 0; i < 17; i ++) {
            [paramsData appendBytes:&byte_time length:sizeof(byte_time)];
        }
    }else{
        NSData *timeData = [self configTimeDataWith:keyModel];
        [paramsData appendData:timeData];
    }
    
    //7-次数 0x00：永久有效 0x01：1次有效
    int8_t byte7 = 0x00;
    if (keyModel.keyType == 3) byte7 = 0x01;
    [paramsData appendBytes:&byte7 length:sizeof(byte7)];
    
    //8-密码长度 9-密码内容 密码内容长度（仅用于密码类型），当为其他类型是长度为0，后续就无密码内容字段
    int8_t byte8 = 0x00;
    [paramsData appendBytes:&byte8 length:sizeof(byte8)];
    //发送指令
    [self sendCommandWith:0x01 paramsData:paramsData];
}

/*
 修改钥匙 - 主要是修改该成员（不是指定的指纹）钥匙的时效性，而非次数
 keyModel - 钥匙模型
 isManager - 是否是管理员
 */
-(void)editFingerAccessWith:(SLLockKeyModel *)keyModel isManager:(BOOL)isManager finish:(SLBluetoothNotifyBlock)finish{
    _editFingerBlock = finish;
    //封装参数
    NSMutableData *paramsData = [[NSMutableData alloc] initWithCapacity:0];
    //1-类型 - 0x00：仅修改某个成员的时效性
    int8_t byte1 = 0x00;
    [paramsData appendBytes:&byte1 length:sizeof(byte1)];
    //2-管理员标志
    int8_t byte2 = isManager ? 0x01 : 0x00;
    [paramsData appendBytes:&byte2 length:sizeof(byte2)];
    //3-成员id
    NSString *uidHex = [DataCoverTool coverFromIntToHex:[keyModel.uid integerValue]];
    NSData *byte3 = [self commodParamsWith:@[uidHex]];
    [paramsData appendData:byte3];
    //4-保存id 0xFFFF 固定值
    int8_t byte4 = 0xFF;
    [paramsData appendBytes:&byte4 length:sizeof(byte4)];
    [paramsData appendBytes:&byte4 length:sizeof(byte4)];
    //5-时效性 - a.次数为 0x00，此时次数为永久有效，可仅处理时效的循环方式。 b.时效的循环方式为 0x00，此时为不循环，可仅处理次数。
    if (keyModel.keyType == 1) {//永久性钥匙 -17个字节
        int8_t byte_time = 0x00;
        for (int i = 0; i < 17; i ++) {
            [paramsData appendBytes:&byte_time length:sizeof(byte_time)];
        }
    }else{
        NSData *timeData = [self configTimeDataWith:keyModel];
        [paramsData appendData:timeData];
    }
    //6-次数 0x00
    BOOL isOnTime = keyModel.keyType == 3;
    int8_t byte7 =  0x00;
    if (isOnTime) byte7 =  0x01;
    [paramsData appendBytes:&byte7 length:sizeof(byte7)];
    //7-禁用状态 0x00：不禁用 0x01：禁用
    BOOL isDisable = [keyModel.status isEqualToString:@"0"];
    int8_t byte6 = isDisable ? 0x01 : 0x00;
    [paramsData appendBytes:&byte6 length:sizeof(byte6)];
    //8-密码长度 8-密码内容 密码内容长度（仅用于密码类型），当为其他类型是长度为0，后续就无密码内容字段
    int8_t byte8 = 0x00;
    [paramsData appendBytes:&byte8 length:sizeof(byte8)];
    //发送指令
    [self sendCommandWith:0x03 paramsData:paramsData];
}

/*
 删除某个成员钥匙的指纹
 uid - 成员id
 accessId - 钥匙id，传空删除该成员
 */
-(void)deleteUserFingerAccessWith:(NSString *)uid accessId:(NSString *)accessId finish:(SLBluetoothNotifyBlock)finish{
    _deleteUserFingerBlock = finish;
    //封装参数
    NSMutableData *paramsData = [[NSMutableData alloc] initWithCapacity:0];
    BOOL isDeleteAll = kSTRING(accessId).length == 0;
    //1-类型 - 0x00：删除成员 0x03：删除指纹
    int8_t byte1 = isDeleteAll ? 0x00 : 0x03;
    [paramsData appendBytes:&byte1 length:sizeof(byte1)];
    //2-管理员标志
    int8_t byte2 = 0x01;
    [paramsData appendBytes:&byte2 length:sizeof(byte2)];
    //3-成员id
    NSString *uidHex = [DataCoverTool coverFromIntToHex:[uid integerValue]];
    NSData *byte3 = [self commodParamsWith:@[uidHex]];
    [paramsData appendData:byte3];
    //4-钥匙id
    if (isDeleteAll) {//0xFFFF 固定值
        int8_t byte4 = 0xFF;
        [paramsData appendBytes:&byte4 length:sizeof(byte4)];
        [paramsData appendBytes:&byte4 length:sizeof(byte4)];
    }else{
        NSData *idData = [DataCoverTool setId:[accessId intValue]];
        [paramsData appendData:idData];
    }
    //5-删除方式 0x00:删除某个成员下的所有开锁方式 0x01：删除某个成员下的某一个开锁方式
    int8_t byte5 = isDeleteAll ? 0x00 : 0x01;
    [paramsData appendBytes:&byte5 length:sizeof(byte5)];
    //发送指令
    [self sendCommandWith:0x02 paramsData:paramsData];
}

/*
 获取某成员id的钥匙数据 - 当前只获取USBkey录入的数据
 uid - 成员id 不传则为所有的钥匙数据
 */
-(void)getFingerAccessDataWith:(NSString *)uid finish:(SLGetFingerDatasBlock)finish{
    _getFingerDatasBlock = finish;
    //0x03：指纹
    _keyBufferData = nil;
    _keyBufferData = [[NSMutableData alloc] init];
    _commondValue = kSTRING(uid);
    NSData *paramsData = [self commodParamsWith:@[@"03"]];
    [self sendCommandWith:0x04 paramsData:paramsData];
}

/*
 获取开锁日志信息
 */
-(void)getDeviceOpenLogDataWith:(SLBluetoothDataBlock)finish{
    _getOpenLogDatasBlock = finish;
    //0x03：指纹
    _openLogBufferData = nil;
    _openLogBufferData = [[NSMutableData alloc] init];
    NSData *paramsData = [self commodParamsWith:@[@"03"]];
    [self sendCommandWith:0x5e paramsData:paramsData];
}

/*
 获取告警的日志信息
 */
-(void)getDeviceWarnLogDataWith:(SLBluetoothDataBlock)finish{
    _getWarnLogDatasBlock = finish;
    _warnBufferData = nil;
    _warnBufferData = [[NSMutableData alloc] init];
    [self sendCommandWith:0x57 paramsData:nil];
}

/*
 固件升级
 FirmwareData - 固件升级文件的data数据
 */
-(void)startUpdateFirmwareWith:(NSData *)firmwareData finish:(SLUpdateFirmwareBlock)finish{
    _updateFirmwareBlock = finish;
    _packetIndex = 1;
    _firmwareData = firmwareData;
    //第一步 - 开启OTA模式
    [self sendCommandWith:0xA0 paramsData:nil];
}

/*
 开始传输固件包
 */
-(void)startUploadFirmwareData{
    //封装数据包
    NSMutableData *paramsData = [[NSMutableData alloc] init];
    //1.总包数（2字节） 升级文件大小/每包数据大小算出
    int total = (int)(_firmwareData.length / _packetSize);
    NSData *totalData = [DataCoverTool setId:total];
    [paramsData appendData:totalData];
    //2.当前包数（2字节）
    NSData *packetIndexData = [DataCoverTool setId:(int)_packetIndex];
    [paramsData appendData:packetIndexData];
    //3.数据（n字节）根据上面0xA1里面数据包的大小 = 当前下标
    NSInteger offset = (_packetIndex - 1)*_packetSize;
    NSRange range;
    if (offset+_packetSize > _firmwareData.length) {
        range = NSMakeRange(offset, _firmwareData.length-_packetSize);
    }else{
        range = NSMakeRange(offset, _packetSize);
    }
    NSLog(@"开始传输固件包 range = %@ _packetIndex = %ld",NSStringFromRange(range),_packetIndex);
    NSData *packetData = [_firmwareData subdataWithRange:range];
    [paramsData appendData:packetData];
    //开始上传固件包
    [self sendCommandWith:0xA2 paramsData:paramsData];
}

/*
 结束OTA升级
 */
-(void)stopUploadFirmwareData{
    [self sendCommandWith:0xA3 paramsData:nil];
}

#pragma mark -
#pragma mark - ================<蓝牙指令封装 - 网关>===============
/*
 设置网关的wifi信息
 */
-(void)setGateWifiInfoWith:(NSString *)wifiName pswd:(NSString *)pswd finish:(SLBluetoothNotifyBlock)finish{
    _setWifiBlock = finish;
    NSMutableData *paramsData = [NSMutableData new];
    //1.名称及字节长度
    NSData *nameData = [DataCoverTool coverFromStringToHexData:wifiName];
    NSData *nameLength = [self commodParamsWith:@[[DataCoverTool coverFromIntToHex:nameData.length]]];
    [paramsData appendData:nameLength];
    [paramsData appendData:nameData];
    //2.密码及字节长度
    NSData *pswdData = [DataCoverTool coverFromStringToHexData:pswd];
    NSData *pswdLength = [self commodParamsWith:@[[DataCoverTool coverFromIntToHex:pswdData.length]]];
    [paramsData appendData:pswdLength];
    [paramsData appendData:pswdData];
    
    [self sendCommandWith:0x10 paramsData:paramsData];
    [self startTimerWithBusiType:@"commondTimeout"];
}

/*
 设置网关的MQTT主题
 */
-(void)setGateMqttThemeWith:(NSString *)theme finish:(SLBluetoothNotifyBlock)finish{
    _setMqttBlock = finish;
    NSMutableData *paramsData = [NSMutableData new];
    NSData *themeData = [DataCoverTool coverFromStringToHexData:[NSString stringWithFormat:@"/topic/%@",theme]];
    [paramsData appendData:themeData];
    [self sendCommandWith:0x12 paramsData:paramsData];
    [self startTimerWithBusiType:@"commondTimeout"];
}

/*
 获取网关macaddress
 */
-(void)getGateMacAddressWith:(SLBluetoothNotifyBlock)finish{
    _getMacAddressBlock = finish;
    [self sendCommandWith:0x15 paramsData:nil];
    [self startTimerWithBusiType:@"commondTimeout"];
}

/*
 获取网关的wifi信息
 */
-(void)getGateWifiInfoWith:(SLBluetoothDataBlock)finish{
    
}

/*
 获取网关的MQTT主题
 */
-(void)getGateThemeInfoWith:(SLBluetoothDataBlock)finish{
    
}

/*
 网关连接wifi
 */
-(void)setGateStartConnectWifiWith:(SLBluetoothNotifyBlock)finish{
    _setConnectWifiBlock = finish;
    [self sendCommandWith:0x14 paramsData:nil];
    [self startTimerWithBusiType:@"commondTimeout"];
}

#pragma mark -
#pragma mark - ================<辅助方法>===============
/*
 配置时效性数据
 startTime - 2018-01-26 08:00:00
 endTime - 2018-01-27 08:00:00
 weekDays - 一周重复时间 例如@[0,1,2,3,4,5,6]//分别代表周日-周六
 dayStart - 一天的开始时间 - 时间段钥匙有值
 dayEnd - 一天的结束时间 - 时间段钥匙有值
 */
-(NSData *)configTimeDataWith:(SLLockKeyModel *)keyModel{
    NSMutableData *timeData = [[NSMutableData alloc] initWithCapacity:0];
    //时间范围
    NSData *rangeData = [self rangeFromStartTime:keyModel.startTime endTime:keyModel.endTime];
    [timeData appendData:rangeData];
    //一次性钥匙没有循环方式
    if (keyModel.keyType == 3) {
        int8_t byte_time = 0x00;
        for (int i = 0; i < 9; i ++) {
            [timeData appendBytes:&byte_time length:sizeof(byte_time)];
        }
        return timeData;
    }
    //周循环或不循环 0x00：不循环 0x02：周循环
    int8_t byte = keyModel.weekDays.count > 0 ? 0x02 : 0x00;
    [timeData appendBytes:&byte length:sizeof(byte)];
    //循环标志位
    int8_t flagByte = 0x00;
    [timeData appendBytes:&flagByte length:sizeof(flagByte)];
    [timeData appendBytes:&flagByte length:sizeof(flagByte)];
    [timeData appendBytes:&flagByte length:sizeof(flagByte)];
    if (keyModel.weekDays.count > 0) {
        int8_t weekFlag = [self weekdayMaskFromArray:keyModel.weekDays];
        [timeData appendBytes:&weekFlag length:sizeof(weekFlag)];
    }else{
        [timeData appendBytes:&flagByte length:sizeof(flagByte)];
    }
    //一天起止时间
    if (kSTRING(keyModel.dayStart).length == 0) {
        if (keyModel.startTime.length > 0) {
            keyModel.dayStart = [NSString convertDateString:keyModel.startTime outFormart:@"HH:mm"];
        }else{
            keyModel.dayStart = @"08:00";
        }
    }
    if (kSTRING(keyModel.dayEnd).length == 0) {
        if (keyModel.endTime.length > 0) {
            keyModel.dayEnd = [NSString convertDateString:keyModel.endTime outFormart:@"HH:mm"];
        }else{
            keyModel.dayEnd = @"18:00";
        }
    }
    NSData *dayRangeData = [self dataWithDayStart:keyModel.dayStart dayEnd:keyModel.dayEnd];
    [timeData appendData:dayRangeData];
    return timeData;
}

-(int8_t)weekdayMaskFromArray:(NSArray<NSString *> *)weekDays{
    NSUInteger mask = 0;
    for (NSString *weekday in weekDays) {
        NSInteger day = [weekday integerValue];
        if (day >= 0 && day <= 6) {
            mask |= (1 << day);
        }
    }
    return (int8_t)mask;
}

- (NSArray<NSString *> *)weekdaysFromMaskData:(NSData *)data{
    if ([data length] != 1) {
        return nil; // 确保传入数据长度为1字节
    }
    const uint8_t *dataBuffer = (const uint8_t *)[data bytes];
    uint8_t mask = dataBuffer[0]; // 取出字节的值
    NSMutableArray<NSString *> *weekdays = [NSMutableArray array];
    for (NSUInteger i = 0; i < 7; i++) {
        // 检查第 i 位是否被设置
        if (mask & (1 << i)) {
            [weekdays addObject:[NSString stringWithFormat:@"%lu", (unsigned long)i]];
        }
    }
    return [weekdays copy];
}

-(NSData *)rangeFromStartTime:(NSString *)startTime endTime:(NSString *)endTime {
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSDate *startDate = [formatter dateFromString:startTime];
    NSTimeInterval startTimestamp = [startDate timeIntervalSince1970];
    NSDate *endDate = [formatter dateFromString:endTime];
    NSTimeInterval endTimestamp = [endDate timeIntervalSince1970];
   
    NSString *sHexStr = [NSString stringWithFormat:@"%08X", (uint32_t)startTimestamp];
    NSData *startData =  [self dataWithHexString:sHexStr];
    
    NSString *eHexStr = [NSString stringWithFormat:@"%08X", (uint32_t)endTimestamp];
    NSData *endData =  [self dataWithHexString:eHexStr];
    NSMutableData *data = [[NSMutableData alloc] initWithCapacity:0];
    // 遍历每两个字符,转换为对应的字节值
    [data appendData:startData];
    [data appendData:endData];
    return data;
}

-(NSData *)timeToHexData:(NSDate *)date{
    NSInteger timestamp = [date timeIntervalSince1970];
    NSString *sHexStr = [NSString stringWithFormat:@"%08X", (uint32_t)timestamp];
    NSData *data =  [self dataWithHexString:sHexStr];
    return data;
}

-(NSData *)dataWithDayStart:(NSString *)dayStart dayEnd:(NSString *)dayEnd{
    // 解析开始时间和结束时间
    NSArray *startComponents = [dayStart componentsSeparatedByString:@":"];
    NSArray *endComponents = [dayEnd componentsSeparatedByString:@":"];

    // 转换小时和分钟为十六进制字符串
    NSString *startHourHex = [NSString stringWithFormat:@"%02X", [startComponents[0] intValue]];
    NSString *startMinuteHex = [NSString stringWithFormat:@"%02X", [startComponents[1] intValue]];
    NSString *endHourHex = [NSString stringWithFormat:@"%02X", [endComponents[0] intValue]];
    NSString *endMinuteHex = [NSString stringWithFormat:@"%02X", [endComponents[1] intValue]];
    // 拼接开始时间和结束时间的十六进制字符串
    NSString *hexString = [NSString stringWithFormat:@"%@%@ %@%@", startHourHex, startMinuteHex, endHourHex, endMinuteHex];
    
    // 将十六进制字符串转换为NSData
    return [self dataWithHexString:hexString];
}

-(NSData *)dataWithHexString:(NSString *)hexStr {
    hexStr = [hexStr stringByReplacingOccurrencesOfString:@" " withString:@""];
    hexStr = [hexStr lowercaseString];
    NSUInteger len = hexStr.length;
    if (!len) return nil;
    unichar *buf = malloc(sizeof(unichar) * len);
    if (!buf) return nil;
    [hexStr getCharacters:buf range:NSMakeRange(0, len)];
    
    NSMutableData *result = [NSMutableData data];
    unsigned char bytes;
    char str[3] = { '\0', '\0', '\0' };
    int i;
    for (i = 0; i < len / 2; i++) {
        str[0] = buf[i * 2];
        str[1] = buf[i * 2 + 1];
        bytes = strtol(str, NULL, 16);
        [result appendBytes:&bytes length:1];
    }
    free(buf);
    return result;
}

-(unsigned char)checkCrc:(unsigned char *)buffer length:(unsigned short)length {
    unsigned short i = 0;
    unsigned char sum = 0;
    
    for (i = 0; i < length; i++) {
        sum = (sum ^ (buffer[i])) + i;
    }
    return sum;
}

/*
 @params @[@"01",@"00"]
 
 */
-(NSData *)commodParamsWith:(NSArray *)params {
    NSMutableData *data = [[NSMutableData alloc] initWithCapacity:0];
    [params enumerateObjectsUsingBlock:^(NSString *obj, NSUInteger idx, BOOL * _Nonnull stop) {
        const char *str = [obj UTF8String];
        // 将字符串转换为整数
        int value = (int)strtol(str, NULL, 16); // 使用基数 16 可直接转换为十六进制
        int8_t byte = (int8_t)value;
        [data appendBytes:&byte length:sizeof(byte)];
    }];
    return data;
}

-(NSArray<SLLockFingerModel *> *)parseFingerFromData:(NSData *)data {
    NSUInteger dataLength = [data length];
    NSInteger byteCount = 26;
    // 检查数据长度是否是26的整数倍
    if (dataLength % byteCount != 0) {
        return @[];
    }
    
    NSUInteger packageCount = dataLength / byteCount;
    NSMutableArray *packageModels = [NSMutableArray arrayWithCapacity:packageCount];
    const unsigned char *dataBuffer = (const unsigned char *)[data bytes];
    
    for (NSUInteger i = 0; i < packageCount; i++) {
        SLLockKeyModel *keyModel = [[SLLockKeyModel alloc] init];
        SLLockFingerModel *fingerModel = [[SLLockFingerModel alloc] init];
        // 解析保存ID（前 2 个字节）
        fingerModel.accessId = kSTRING(@((dataBuffer[i * byteCount] << 8) | dataBuffer[i * 26 + 1]));
        // 解析类型（第 3 个字节）- 指纹锁1
        keyModel.lockType = 1;
        // 解析UID（第 4 个字节）
        fingerModel.uid = kSTRING(@(dataBuffer[i * byteCount + 3]));
        keyModel.uid = fingerModel.uid;
        // 解析类型（第 5 个字节）
        keyModel.isUsbKey = kSTRING(@(dataBuffer[i * byteCount + 4]));
        //解析次数（第 6 个字节）
        NSString *useCount = kSTRING(@(dataBuffer[i * byteCount + 5]));
        //解析一次性钥匙是否已使用 (第 7 个字节）（单次指纹使用标志（1字节）：0（未使用），1（已使用）（非单次指纹默认填0）
        NSString *isUse = kSTRING(@(dataBuffer[i * byteCount + 6]));
        keyModel.isUse = isUse;
        //解析禁用状态（第 8 个字节）
        NSString *disableStatus = [kSTRING(@(dataBuffer[i * byteCount + 7])) isEqualToString:@"1"] ? @"0" : @"1";
        keyModel.status = disableStatus;
        // 解析时效性标志（第 9 个字节）0-没有时效性 1-有时效性
        NSString *validityFlag = kSTRING(@(dataBuffer[i * byteCount + 8]));
        //默认永久钥匙
        NSInteger keyType = 1;
        //有时效性 - 一次性钥匙或时间段钥匙
        if ([validityFlag isEqualToString:@"1"]){
            keyType = [useCount isEqualToString:@"1"] ? 3 : 2;
        }
        NSString *msg = [NSString stringWithFormat:@"同步钥匙数据 成员id %@ 保存id %@",fingerModel.uid,fingerModel.accessId];
        NSLog(@"%@",msg);
        [UserManager updateLogViewWithMessage:msg needUnicode:NO];
        keyModel.keyType = keyType;
        //解析时效性
        if (keyType != 1) {
            NSMutableData *validityData = [NSMutableData dataWithLength:17];
            memcpy(validityData.mutableBytes, &dataBuffer[i * byteCount + 9], 17);
            [self parseTimeDataWith:validityData keyModel:keyModel];
        }
        keyModel.fingers = @[fingerModel];
        [packageModels addObject:keyModel];
    }
    return [packageModels copy];
}

-(void)parseTimeDataWith:(NSData *)data keyModel:(SLLockKeyModel *)keyModel{
    NSString *startTime;NSString *endTime;
    NSString *dayStart;NSString *dayEnd;NSArray *weekDays;
    
    NSData *data1 = [data subdataWithRange:NSMakeRange(0, 4)];
    startTime = [self timeStringFromData:data1];
    
    NSData *data2 = [data subdataWithRange:NSMakeRange(4, 4)];
    endTime = [self timeStringFromData:data2];
    
    NSData *data3 = [data subdataWithRange:NSMakeRange(data.length-5, 1)];
    weekDays = [self weekdaysFromMaskData:data3];
    
    NSData *data4 = [data subdataWithRange:NSMakeRange(data.length-4, 2)];
    dayStart = [self dayTimeStringFromData:data4];
    
    NSData *data5 = [data subdataWithRange:NSMakeRange(data.length-2, 2)];
    dayEnd = [self dayTimeStringFromData:data5];
    
    keyModel.startTime = startTime;
    keyModel.endTime = endTime;
    keyModel.weekDays = weekDays;
    keyModel.dayStart = dayStart;
    keyModel.dayEnd = dayEnd;
}

- (NSArray<SLLockLogModel *> *)parseOpenLogFromData:(NSData *)data {
    NSUInteger dataLength = [data length];
    // 检查数据长度是否是7的整数倍
    if (dataLength % 7 != 0) {
        return nil;
    }
    
    NSUInteger packageCount = dataLength / 7;
    NSMutableArray *packageModels = [NSMutableArray arrayWithCapacity:packageCount];
    const unsigned char *dataBuffer = (const unsigned char *)[data bytes];
    for (NSUInteger i = 0; i < packageCount; i++) {
        SLLockLogModel *model = [[SLLockLogModel alloc] init];
        // 解析 accessId（第 2 和第 3 个字节）
        model.accessId = kSTRING(@((dataBuffer[i * 7 + 1] << 8) | dataBuffer[i * 7 + 2]));
        // 设置 unlockType
        model.unlockType = @"3";
        // 解析 time（后 4 个字节）
        NSString *timeHexStr = kSTRING(@((dataBuffer[i * 7 + 3] << 24) | (dataBuffer[i * 7 + 4] << 16) | (dataBuffer[i * 7 + 5] << 8) | dataBuffer[i * 7 + 6]));
        model.unlockTime = timeHexStr;
        [packageModels addObject:model];
        
        NSString *msg = [NSString stringWithFormat:@"同步开锁记录 保存id %@ unlockType %@ time %@",model.accessId,model.unlockType,model.unlockTime];
        NSLog(@"%@",msg);
        [UserManager updateLogViewWithMessage:msg needUnicode:NO];
    }
    return [packageModels copy];
}

-(NSArray<SLLockFingerModel *> *)parseWarnLogFromData:(NSData *)data{
    NSUInteger dataLength = [data length];
    // 检查数据长度是否是5的整数倍
    if (dataLength % 5 != 0) {
        return nil;
    }
    NSUInteger packageCount = dataLength / 5;
    NSMutableArray *packageModels = [NSMutableArray arrayWithCapacity:packageCount];
    const unsigned char *dataBuffer = (const unsigned char *)[data bytes];
    for (NSUInteger i = 0; i < packageCount; i++) {
        SLLockLogModel *model = [[SLLockLogModel alloc] init];
        // 解析时间戳（前 4 个字节）
        NSUInteger timestamp = ((NSUInteger)dataBuffer[i * 5] << 24) |
                               ((NSUInteger)dataBuffer[i * 5 + 1] << 16) |
                               ((NSUInteger)dataBuffer[i * 5 + 2] << 8) |
                               (NSUInteger)dataBuffer[i * 5 + 3];
        model.unlockTime = kSTRING(@(timestamp)); // 将时间戳转换为字符串
        // 解析状态标识（第 5 个字节）
        model.warnType = kSTRING(@(dataBuffer[i * 5 + 4])); // 直接使用单个字节状态
        [packageModels addObject:model];
        
        NSString *msg = [NSString stringWithFormat:@"同步告警信息  warnType %@ time %@",model.warnType,model.unlockTime];
        NSLog(@"%@",msg);
        [UserManager updateLogViewWithMessage:msg needUnicode:NO];
    }
    
    return [packageModels copy];
}

- (NSUInteger)timestampFromData:(NSData *)data {
    // 检查数据长度是否为4
    if ([data length] != 4) {
        return 0; // 或者根据需求返回其他值，例如错误码
    }
    
    const unsigned char *dataBuffer = (const unsigned char *)[data bytes];
    
    // 组合四个字节为一个时间戳
    NSUInteger timestamp = ((NSUInteger)dataBuffer[0] << 24) |
                           ((NSUInteger)dataBuffer[1] << 16) |
                           ((NSUInteger)dataBuffer[2] << 8) |
                           ((NSUInteger)dataBuffer[3]);
    
    return timestamp;
}

- (NSString *)dayTimeStringFromData:(NSData *)data {
    if ([data length] != 2) {
        return nil; // 确保传入数据长度为2字节
    }
    const unsigned char *dataBuffer = (const unsigned char *)[data bytes];
    // 组合为一个16位的时间值
    uint16_t timeValue = (dataBuffer[0] << 8) | dataBuffer[1];
    // 提取小时和分钟
    NSUInteger hours = (timeValue >> 8) & 0xFF; // 取高8位作为小时
    NSUInteger minutes = timeValue & 0xFF;      // 取低8位作为分钟
    // 格式化为 HH:mm
    return [NSString stringWithFormat:@"%02lu:%02lu", (unsigned long)hours, (unsigned long)minutes];
}


-(NSString *)timeStringFromData:(NSData *)data{
    if (data.length != 4) {
        return nil;
    }

    const unsigned char *bytes = (const unsigned char *)[data bytes];
    uint32_t timestamp = (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3];

    NSDate *date = [NSDate dateWithTimeIntervalSince1970:timestamp];
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSString *timeString = [formatter stringFromDate:date];

    return timeString;
}

-(int8_t)int8ValueFromString:(NSString *)string{
    if (string.length != 2) {
        return 0;
    }
    NSScanner *scanner = [NSScanner scannerWithString:string];
    unsigned int value;
    if (![scanner scanHexInt:&value]) {
        return 0;
    }
    if (value < 0 || value > 0xFF) {
        return 0;
    }
    return (int8_t)value;
}

- (NSString *)macStringFromData:(NSData *)data {
    if (data == nil || data.length == 0 || data.length != 6) {
        return @"";
    }
    NSMutableString *hexString = [NSMutableString stringWithCapacity:17]; // 6 bytes * 2 + 5 colons
    const unsigned char *bytes = (const unsigned char *)[data bytes];
    for (NSInteger i = 0; i < data.length; i++) {
        // 将每个字节的值转换为十六进制字符串
        [hexString appendFormat:@"%02X", bytes[i]];
        // 添加分隔符，避免在最后一个字节后添加
        if (i < data.length - 1) {
            [hexString appendString:@":"];
        }
    }
    NSString *finalStr = [self reversedMacString:hexString];
    return [finalStr copy];
}

-(NSString *)parseMacAddressFromString:(NSString *)hexString{
    NSMutableString *macAddress = [NSMutableString string];
    for (NSInteger i = 0; i < hexString.length; i += 2) {
        NSString *substring = [hexString substringWithRange:NSMakeRange(i, 2)];
        [macAddress appendFormat:@"%@:", substring];
    }
    if (macAddress.length > 0) {
        [macAddress deleteCharactersInRange:NSMakeRange(macAddress.length - 1, 1)]; // 删除最后一个多余的冒号
    }
    return macAddress;
}

- (NSString *)reversedMacString:(NSString *)macString {
    // 拆分字符串为数组
    NSArray *components = [macString componentsSeparatedByString:@":"];
    // 反转数组
    NSArray *reversedComponents = [[components reverseObjectEnumerator] allObjects];
    // 重新组合为字符串
    NSString *reversedMacString = [reversedComponents componentsJoinedByString:@":"];
    return reversedMacString;
}

-(NSData *)dataFromInteger:(NSInteger)value{
    NSMutableData *data = [NSMutableData dataWithLength:4];
    uint8_t *bytes = (uint8_t *)[data mutableBytes];
    
    bytes[0] = (uint8_t)((value >> 24) & 0xFF);
    bytes[1] = (uint8_t)((value >> 16) & 0xFF);
    bytes[2] = (uint8_t)((value >> 8) & 0xFF);
    bytes[3] = (uint8_t)(value & 0xFF);
    
    return [data copy];
}

#pragma mark -
#pragma mark - ================<解密广播数据，获取设备的productId和deviceNo>===============
-(NSDictionary *)parseAdvertisementData:(NSDictionary<NSString *,id> *)advertisementData{
    NSLog(@"adData = %@",advertisementData);
    // 解析 Manufacturer Data
    NSData *manufacturerData = advertisementData[CBAdvertisementDataManufacturerDataKey];
    NSArray *uuidData = advertisementData[CBAdvertisementDataServiceUUIDsKey];
    CBUUID *uuid = uuidData[0];
    BOOL isBridge = [kSTRING(uuid.UUIDString) isEqualToString:@"0219"];
    
    id serviceData = advertisementData[CBAdvertisementDataServiceDataKey];
    NSMutableDictionary *info = [NSMutableDictionary new];
    CBUUID *serUUID = [serviceData allKeys][0];
    NSData *orgData = [NSData data];
    NSString *isBindFlag = @"0";
    NSString *isAutoConnectFlag = @"0";
    NSMutableData *totalData = [[NSMutableData alloc] init];
//    NSData *data = [advertisementData objectForKey:@"kCBAdvDataManufacturerData"];
    // 解析扫描响应数据
    //网关设备
    if (isBridge) {
        isBindFlag = @"0";
        isAutoConnectFlag = @"0";
        totalData = [[NSMutableData alloc] initWithData:[self swapFirstTwoBytesOfData:serUUID.data]];
        for (CBUUID *uuid in serviceData) {
            NSData *data = serviceData[uuid];
            [totalData appendData:data];
        }
        orgData = totalData;
    }
    //智锁设备
    else{
        for (CBUUID *uuid in serviceData) {
            NSData *data = serviceData[uuid];
            [totalData appendData:data];
        }
        [totalData appendData:manufacturerData];
        if (totalData.length != 20) {
            return nil;
        }
        NSString *flag = serUUID.UUIDString;
   
        if (flag.length == 4) {
            isAutoConnectFlag = [[flag substringWithRange:NSMakeRange(0, 2)] isEqualToString:@"01"] ? @"1" : @"0";
            isBindFlag = [[flag substringWithRange:NSMakeRange(2, 2)] isEqualToString:@"01"] ? @"1" : @"0";
        }
        orgData = [[NSData alloc] initWithData:[totalData subdataWithRange:NSMakeRange(4, totalData.length-4)]];
        
    }
    NSString *key = @"6fwvnchuye15s9af";
    NSData *keyData =  [key dataUsingEncoding:NSUTF8StringEncoding];
    //解密后的16个字节数据
    NSData *finalData = [SLBluetoothManager decryptData:orgData withKey:keyData];
    NSString *hexStr = [DataCoverTool coverFromHexDataToStr:finalData];
    NSString *finalStr = [DataCoverTool coverFromHexStringToStr:hexStr];
    if (finalStr.length != 16) {
        return nil;
    }
    NSString *productId = [finalStr substringWithRange:NSMakeRange(0, 8)];
    NSString *deviceNo = [finalStr substringWithRange:NSMakeRange(8, 8)];
    [info setObject:productId forKey:@"productId"];
    [info setObject:deviceNo forKey:@"deviceNo"];
    [info setObject:kSTRING(@(isBridge)) forKey:@"isBridge"];
    [info setObject:isBindFlag forKey:@"isBindFlag"];
    [info setObject:isAutoConnectFlag forKey:@"isAutoConnectFlag"];
    return info;
}

-(NSData *)dataWith:(NSData *)data{
    NSMutableData *muData = [[NSMutableData alloc] initWithData:data];
    // 对后4个字节进行异或解密
    for (int i = 0; i < 4; i++) {
        ((uint8_t *)muData.mutableBytes)[32 + i] ^= ((uint8_t *)muData.mutableBytes)[i];
    }
    
    return muData;
}

-(NSData *)swapFirstTwoBytesOfData:(NSData *)data {
    // 检查数据长度是否至少为2个字节，如果小于2则直接返回原数据
    if (data.length < 2) {
        return data;
    }
    
    // 创建可变数据副本以便修改
    NSMutableData *mutableData = [data mutableCopy];
    // 获取可变数据的字节指针
    unsigned char *bytes = (unsigned char *)[mutableData mutableBytes];
    
    // 交换第一个和第二个字节的位置
    unsigned char temp = bytes[0];
    bytes[0] = bytes[1];
    bytes[1] = temp;
    
    // 返回修改后的不可变数据
    return [NSData dataWithData:mutableData];
}

+(NSData *)decryptData:(NSData *)data withKey:(NSData *)key {
    // 检查密钥长度
    if (key.length != kCCKeySizeAES128 && key.length != kCCKeySizeAES192 && key.length != kCCKeySizeAES256) {
        NSLog(@"Invalid key length");
        return nil;
    }
    
    size_t dataOutLength;
    NSMutableData *decryptedData = [NSMutableData dataWithLength:data.length];

    CCCryptorStatus result = CCCrypt(kCCDecrypt,
                                      kCCAlgorithmAES,
                                      kCCOptionPKCS7Padding, // 使用填充
                                      key.bytes,
                                      key.length,
                                      NULL, // ECB 模式不需要 IV
                                      data.bytes,
                                      data.length,
                                      decryptedData.mutableBytes,
                                      decryptedData.length,
                                      &dataOutLength);

    if (result == kCCSuccess) {
        decryptedData.length = dataOutLength; // 设置正确的长度
        return decryptedData;
    }
    return nil; // 解密失败
}
@end



